define([ "jquery", "application", "globalsettings" ], function($, app) {
  console.log("----------components.js")
  if ($.Component) {
    return $.Component;
  }
  try {
    var getProp = function(obj, prop, defaultValue) {
      var res = defaultValue;
      if (!isEmpty(obj) && !isEmpty(prop)) {
        res = obj[prop];
        if ($.isFunction(res)) {
          res = res();
        }
        if (isEmpty(res)) {
          res = defaultValue;
        }
      }
      return res;
    }

    /**
     * 获得逻辑视图的宽度.
     */
    var getViewWidth = function() {
      return app.logicView.width;
    };
    /**
     * 获得逻辑视图的高度.
     */
    var getViewHeight = function() {
      return app.logicView.height;
    };
    /**
     * 定义组件类.
     */
    window.Component = defineClass(Object, function(settings) {
      var self = this;
      this.settings=$.extend({
	      name:"",
	      //top:0,left:0,width:-1,height:-1,
	      visible:true,isSaveRestore:true
	  }, settings);
      self.top = self.settings.top;
      self.left = self.settings.left;
      self.width = self.settings.width;
      self.height = self.settings.height;
      self.name = self.settings.name;
      if ($.isFunction(self.settings.render)) {
        self.renderComp = self.settings.render;
      }
    });

    Component.prototype.name = "";
    Component.prototype.top = 0;
    Component.prototype.left = 0;
    Component.prototype.width = 1;
    Component.prototype.height = 1;
    Component.prototype.visible = true;
    Component.prototype.isSaveRestore = true;

    Component.prototype.renderComp = $.noop;

    /**
     * 定义render方法，用于绘制组件.
     */
    defineFunction.call(Component.prototype, "render", function(target, c, vw,
        vh, bw, bh) {
      if (!this.visible) {
        return;
      }
      var self = this;
      var _execSave = false;
      var args = arguments;
      if (this.isSaveRestore) {
        c.render(function() {
          self.renderComp && $.isFunction(self.renderComp)
              && self.renderComp.apply(self, args);
        });
      } else {
        self.renderComp && $.isFunction(self.renderComp)
            && self.renderComp.apply(self, args);
      }

      if (this.onClick && $.isFunction(this.onClick)) {
        target.whenClick(this.left, this.top, this.width, this.height,
            function(ev, data) {
              this.onClick.apply(self, args);
            });
      }

    }, "Component");

    /**
     * 组合组件.
     */
    window.GroupComponent = defineClass(Component, function(settings) {
      var self = this;
      self.settings = $.extend({
        top : 0,
        left : 0,
        width : -1,
        height : -1,
        comps : []
      }, self.settings, settings);
      self.comps = self.settings.comps;
      self.top = self.settings.top;
      self.left = self.settings.left;
      self.width = self.settings.width;
      self.height = self.settings.height;
    }, "GroupComponent");

    GroupComponent.prototype.comps = [];
    defineFunction.call(GroupComponent.prototype, "addComp",function(comp){this.comps.push(comp)},"GroupComponent");
    defineFunction.call(GroupComponent.prototype, "clear",function(){this.comps.length=0;},"GroupComponent");
    defineFunction.call(GroupComponent.prototype, "renderComp", function(t, c,
        vw, vh) {
      try{
      var self = this;
      var args = arguments;
      $(self.comps).each(function() {
        var comp = this;
        c.render(function() {
          // c.t(comp.left,comp.top);
          comp.render && comp.render.apply(comp, args);
          self.width = Math.max(self.width, comp.left + comp.width);
          self.height = Math.max(self.height, comp.top + comp.height);
          // console.log("height:"+self.height+","+comp.top+","+comp.height+","+(comp.top+comp.height)+","+comp.constructor.name);
        });
        // console.log("=================")
      });
      }catch(e){console.log(e);}
    }, "GroupComponent");

    /**
     * 背景类.
     */
    window.Background = defineClass(Component, function(settings) {
      var self = this;
      self.settings = $.extend({ image:undefined ,color:"white" },settings);
    }, "Background");

    Background.prototype.status = 0;

    defineFunction.call(Background.prototype, "renderComp", function(t, c, vw,
        vh) {
      var self = this;
      var color = (self.settings.color);
      // 渲染背景色
      color && c.render(function() {
        c.fillStyle = color;
        c.fillRect(0, 0, vw, vh);
      });
      // 加载背景图.
      if (!self.image) {
        var image_src = self.settings.image;
        if (image_src) {
          self.image = new Image();
          self.image.onload = function() {
            self.imageLoaded = true;
          };
          self.image.src = image_src;
        }
      }
      self.imageLoaded && c.render(function() {
        c.drawImage(self.image, 0, 0, vw, vh);
      });

    });

    /**
     * 文本按钮.
     */
    window.TextButton = defClass(Component, function(settings) {
      try {
	  var s=$.extend(
    {padding:0,radius:5,shadow:true,
     shadowColor:"black",shadowBlur:5,
     shadowOffsetX:3,shadowOffsetY:5},
    settings);
	  this.height=s.height;
	  this.text = s.text;
        this.fontSize = s.fontSize;
        this.font = s.font;// 可以设置为函数
        this.color = s.color;
        this.bgColor = s.bgColor;
        this.onClick = s.onClick;
        this.stroke = s.stroke;
        this.isCenter = s.isCenter;
        this.padding=s.padding;
	  this.radius=s.radius;
	  this.settings=s;
        if(!this.padding){
          this.padding=0;
        }
        this.padding2=this.padding*2;
	this.onClick=s.onClick?s.onClick:$.noop;
      } catch (e) {
        console.log(e);
      }
    }, "TextButton");
    
    window.TextButton.prototype.__desc="文本按钮";

    defFunc(window.TextButton, "renderComp", function(page, c, vw, vh) {
      try {
        var self = this;
        var tw = 0;
        var fs = self.fontSize;
        var fs_h = fs / 2;
        c.render(function() {
          try {
            c.t(self.left, self.top);
            if (self.font) {
              var font = self.font;
              if ($.isFunction(font)) {
                font = font(fs);
              }
              c.font = font;
            }
            tw = c.measureText(self.text).width;
            var tw_h = tw / 2;
            
            if(!self.width){
              self.width=0;
            }
            
            if(!self.height){
              self.height=0;
            }

            var w = (tw+self.padding2) > self.width ? (tw+self.padding2) : self.width;
	    //w+=self.padding2;
            var h = (fs+self.padding2) > self.height ? (fs+self.padding2) : self.height;
	    //h+=self.padding2;
            var w_h = w / 2;
            var h_h = h / 2;
            if (self.isCenter != true) {
		c.t(w_h, h_h);//移动到按钮的中心点，之后所有的算法都是从按钮中心点偏移的
            }
	    if(self.height!=-1){
		self.height=h;
	    }
            
	    if(self.settings.shadow){
		c.shadowColor=self.settings.shadowColor;
		c.shadowBlur=self.settings.shadowBlur;
		c.shadowOffsetX=self.settings.shadowOffsetX;
		c.shadowOffsetY=self.settings.shadowOffsetY;
	    }
            if (self.bgColor) {
              //console.log("text btn bg color 1:"+self.bgColor+"-settings:"+self.settings.bgColor);
              c.fillStyle = self.bgColor;
              c.beginPath();
              //console.log("tw:"+tw+",fs:"+fs+","+-w_h+","+-h_h+","+w+","+h)
	      if(self.radius&&self.radius>0){
		  c.roundRect(-w_h,-h_h,w,h,self.radius);
	      }else{
		  c.rect(-w_h, -h_h, w, h);
              }
	      c.closePath();
              c.fill();
            }
            var color = self.color;
            if (!color) {
              color = "black";
            }
            if (self.stroke == true) {
              c.strokeStyle = color;
              c.strokeText(self.text, -tw_h, 0);
            } else {
              c.fillStyle = color;
              c.fillText(self.text, -tw_h, 0);
            }
            page.whenClick(-w_h, -h_h, w, h, function() {
              return self.onClick();
            });
          } catch (e) {
            console.log(e);
          }
        });
      } catch (e) {
        console.log(e);
      }
    });

    /*
     * 图标按钮
     */
    window.ImageButton = defClass(Component, function(settings) {
      var self = this;
      self.settings = $.extend({
        image : "",
        top : 0,
        left : 0,
        width : 0,
        height : 0,
        onClick : $.noop
      }, settings);
      self.image = self.settings.image;
      self.top = self.settings.top;
      self.left = self.settings.left;
      self.width = self.settings.width;
      self.height = self.settings.height;
      
      
    }, "ImageButton");
    ImageButton.prototype.image = "";
    defineFunction.call(ImageButton.prototype, "renderComp", function(t, c, vw,
        vh) {
      var self = this;
      if ((!self.image) || self.image.trim() == "") {
        return;
      }
      c.render(function() {
        c.t(self.left, self.top);
        var img = imgs[self.image];
        if (img == null) {
          img = new Image();
          imgs[self.image] = img;
          img.loaded = false;
          img.onload = function() {
            this.loaded = true;
          }
          img.src = self.image;
        }
        if (!img.loaded) {
          return;
        }
        if (self.width <= 0) {
          self.width = img.width;
        }
        if (self.height <= 0) {
          self.height = img.height;
        }
        c.drawImage(img, 0, 0, self.width, self.height);
        t.whenClick(0, 0, self.width, self.height, function() {
          var fn = self.settings.onClick;
          fn && $.isFunction(fn) && (function(callback) {
            callback.call(self);
          })(fn);
        });
      });
    });

    /*
     * 头
     */
    window.Header = defClass(Component,
        function() {
          this.title = getProp(this.settings, "title", null);
          this.left = getProp(this.settings, "left", 0);
          this.top = getProp(this.settings, "top", 0);
          this.width = getViewWidth();
          this.height = getProp(this.settings, "height", 1);
          this.fontSize = getProp(this.settings, "fontSize", this.height / 2);
          this.font = FONT.pingfangB(this.fontSize);
          this.color = getProp(this.settings, "color", "white");
          this.backgroundColor = getProp(this.settings, "backgroundColor",
              "black");
        }, "Header");

    Header.prototype.status = 0;
    defineFunction.call(Header.prototype, "renderComp", function(t, c, vw) {
      c.fillStyle = this.backgroundColor;
      c.fillRect(this.left, this.top, this.width, this.height);

      if (this.title) {
        c.t(this.left + this.width / 2, this.top + this.height / 2);
        c.font = this.font;
        c.fillStyle = this.color;
        var tw = c.measureText(this.title).width;
        c.fillText(this.title, -tw / 2, 0);
      }
    }, "Header");

    /*
     * 页脚
     */
    window.Footer = defClass(Header, function() {
    }, "Footer");

    Footer.prototype.status = 0;

    defineFunction.call(Footer.prototype, "renderComp", function(t, c, vw) {
      c.t(0, getViewHeight());
      c.t(0, -this.height);
      this["renderComp::Header"].apply(this, arguments);
    }, "Footer");
    /**
     * 广告栏
     */
    window.Banner = defClass(Component,
        function() {
          this.offsetX = getProp(this.settings, "offsetX", 0);
          this.offsetY = getProp(this.settings, "offsetY", 0);
          this.left = getProp(this.settings, "left", 0);
          this.top = getProp(this.settings, "top", 0);
          this.width = getViewWidth();
          this.height = getProp(this.settings, "height", 1);
          this.backgroundColor = getProp(this.settings, "backgroundColor",
              "black");
          this.imgs = getProp(this.settings, "imgs", []);
          this.lastSwitchTm = new Date().getTime();
          this.idx = 0;
        }, "Banner");
    Banner.prototype.status = 0;
    defineFunction.call(Banner.prototype, "renderComp", function(t, c, vw) {
      c.t(this.offsetX, this.offsetY);

      c.fillStyle = this.backgroundColor;
      c.fillRect(this.left, this.top, this.width, this.height);
    }, "Banner");

    /**
     * 布局.
     */
    window.Layout = defClass(Component, function(settings) {
	    this.comps=[];
    }, "Layout");

    /**
     * 组件列表.
     */
    //Layout.prototype.comps = [];
    /**
     * 向布局中添加组件
     * 
     * @param comp
     */
    Layout.prototype.addComp = function(comp) {
      comp && this.comps.push(comp);
    }
    Layout.prototype.clear = function() {
      this.comps && (this.comps.length = 0);
    }
    // 为绘制当前帧按照绘制准备组件列表
    defineFunction.call(Layout.prototype, "beforeRender", function() {
      var self = this;
      self.curCompsStack = [];
      // $.merge(self.curComps)
    }, "Layout");

    // 清理当前帧组件列表
    defineFunction.call(window.Layout.prototype, "afterRender", function() {
      var self = this;
      self.curCompsStack = undefined;
    }, "Layout");

    defineFunction.call(Layout.prototype, "nextComp", function() {
      var self = this;
      if(!self.curCompsStack){
	  self.curCompsStack=[];
      }
      var res = self.curCompsStack.pop();
      return res;
    }, "Layout");

    defineFunction.call(Layout.prototype, "renderCurComp", function(t, c, vw,
        vh, bw, bh, cur) {
      try {
        cur.renderComp(t, c, vw, vh, bw, bh);
      } catch (e) {
        console.log(e);
      }
    }, "Layout");

    /**
     * 绘制布局.
     */
    defineFunction.call(Layout.prototype, "renderComp", function(t, c, vw, vh,
        bw, bh) {

      var self = this;
      self.beforeRender();

      try {
        var cur = null;
        while (cur = self.nextComp()) {
          self.renderCurComp(t, c, vw, vh, bw, bh, cur);
        }
      } catch (e) {
        console.log(e);
      }

      self.afterRender();

    });

    /**
     * 垂直布局
     */
    window.VerticalLayout = defClass(Layout, function(settings) {
    }, "VerticalLayout");
    VerticalLayout.prototype.status = 0;
    defineFunction.call(VerticalLayout.prototype, "beforeRender", function() {
      var self = this;
      self["beforeRender::Layout"]();
      $.merge(self.curCompsStack, self.comps);
      self.curCompsStack.reverse();
    }, "VerticalLayout");

    defineFunction.call(VerticalLayout.prototype, "renderCurComp", function(t,
        c, vw, vh, bw, bh, cur) {
      var self = this;
      c.render(function() {
        self["renderCurComp::Layout"](t, c, vw, vh, bw, bh, cur);
      });
      c.t(0, cur.height);
      this.height += cur.height;
    }, "VerticalLayout");

    /**
     * Panel
     */
    window.Panel = defClass(Component, function(settings) {
      var self = this;
      var default_settings = {
        page : undefined // 页面对象:用于检测各种事件是否发生
        ,
        top : 0// 绘制时，开始位置的y轴偏移量
        ,
        left : 0// 绘制时，开始位置的x轴偏移量
        ,
        width : 0// 绘制时，滚动面板范围的宽度
        ,
        height : 0
      // 绘制时，滚动面板范围的高度
      };
      self.settings = $.extend({}, default_settings, settings);
      self.top = self.settings.top;
      self.left = self.settings.left;
      self.width = self.settings.width;
      self.height = self.settings.height;
      self.layout = new VerticalLayout();
    }, "Panel");
    //Panel.prototype.layout = new VerticalLayout();
    Panel.prototype.addComp = function(comp) {
      this.layout.addComp(comp)
    }
    
    
    defineFunction.call(Panel.prototype, "clear",function(){
      this.layout.clear();
    });
    

    defineFunction.call(Panel.prototype, "renderComp", function(t, c, vw, vh,
        bw, bh) {
      var self = this;
      c.render(function() {
        self.layout.height = 0;
        self.layout.renderComp(t, c, vw, vh, bw, bh);
        self.contentHeight = self.layout.height;
	//self.height=self.layout.height;
      });
    }, "Panel");

    /*
     * 可滚动面板.
     */
    window.ScrollPanel = defClass(Panel, function(settings) {
      var self = this;
      var default_settings = {
        page : undefined // 页面对象:用于检测各种事件是否发生
        ,
        top : 0// 绘制时，开始位置的y轴偏移量
        ,
        left : 0// 绘制时，开始位置的x轴偏移量
        ,
        width : 0// 绘制时，滚动面板范围的宽度
        ,
        height : 0
      // 绘制时，滚动面板范围的高度
      };
      self.settings = $.extend({}, default_settings, settings);
      self.top = self.settings.top;
      self.left = self.settings.left;
      self.width = self.settings.width;
      self.height = self.settings.height;
    }, "ScrollPanel");

    ScrollPanel.prototype.offset = 0;// 滚动条当前位置
    ScrollPanel.prototype.minOffset = 0;// 滚动条位置最大值
    ScrollPanel.prototype.maxOffset = 0;// 滚动条位置最大值
    ScrollPanel.prototype.contentHeight = -1;// 滚动组件中内容的高度
    ScrollPanel.prototype.speed=0;
    ScrollPanel.prototype.maxSpeed=1000;
    ScrollPanel.prototype.wantOffsetFact=20;
    ScrollPanel.prototype.deta=0;
    
    
    defineFunction.call(ScrollPanel.prototype, "clear",function(){
      this["clear::Panel"]();
      this.offset=0;
      this.contentHeight=0;
    });

    /*
     * 滚动面板的默认布局 ScrollPanel.prototype.layout=new VerticalLayout();
     * 
     * ScrollPanel.prototype.addComp=function(comp){ this.layout.addComp(comp) }
     * ScrollPanel.prototype.clear=function(){ this.layout.clear(); }
     */
    defineFunction.call(ScrollPanel.prototype, "clearScroll",function(page,c,vw,vh,bw,bh){
      var me = this;
      me.speed=0;
      me.deta=0;
      me._count=0;
      me.lastScrollTm=0
      me.curScrollTm=0;
    });
    
    // 可滚动面板的绘制方法.
    defineFunction.call(ScrollPanel.prototype, "renderComp", function(t, c, vw,
        vh, bw, bh) {

      var self = this;
      var page = t;
      c.render(function() {
        c.t(self.settings.left, self.settings.top);
        var scallable = false;
        if (self.contentHeight > 0) {
          scallable = (self.contentHeight > self.height);
          self.maxOffset = 0;
          self.minOffset = (self.height - self.contentHeight);
        }
        c.t(0, self.offset);

        c.beginPath();
        c.rect(0, -self.offset, self.settings.width, self.settings.height);
        c.closePath();
        c.clip();
        
        t.whenScrollMove(0, -self.offset, self.settings.width,
            self.settings.height, function(ev) {
          var d = ev.stepY*vh/bh;
          self.deta = Math.max(Math.abs(self.deta?self.deta:0), Math.abs(d/ev.stepTm))*(d>=0?1:-1);
          self.offset += d;
          self.offset = Math.max(self.minOffset, self.offset);
          self.offset = Math.min(self.maxOffset, self.offset);
          self.scrollEv=ev;
          //console.log(ev.stepY)
        });
        
        
        var se = self.scrollEv;
        if(se){//持续滚动
          
          var tm = $.now();
          var dtm = tm - se.time;//最后一次移动与当前时间的差
          //console.log(self.deta);
          if(dtm>50&&se.detaTm<200&&self.deta!=0){//>50保证在移动后，<200保证快速移动时触发，普通移动不触发,deta!=0自动滚动没有开始
            //console.log(1)
            self.speed=self.deta;///se.detaTm;
            self.deta=0;
            self._count=0;
            //console.log("self.speed:"+self.speed);
          }else if(dtm<50){
            self.speed=0;
          }
          self.lastScrollTm=self.curScrollTm;
          self.curScrollTm=tm;
          self._count+=1;
          if(self.speed&&self.speed!=0&&self.lastScrollTm&&self.curScrollTm){
            //console.log("s:"+self.speed);
            //console.log(self.speed*(self.curScrollTm-self.lastScrollTm));
            self.offset += self.speed*(self.curScrollTm-self.lastScrollTm);
            self.offset = Math.max(self.minOffset, self.offset);
            self.offset = Math.min(self.maxOffset, self.offset);
            
            if(self.offset==self.minOffset||self.minOffset==self.maxOffset){
              self.clearScroll;
            }
            
            if(self._count%10==0){
              self.speed=self.speed>0?Math.sqrt(self.speed):Math.sqrt(-self.speed)*-1;
            }
            
            if(dtm>10000){
              self.speed=0;
            }
            
          }
          
          
          //console.log(self.speed);//*(tm-se.time))
          /*
          self.offset += self.speed*(tm-se.time);
          self.offset = Math.max(self.minOffset, self.offset);
          self.offset = Math.min(self.maxOffset, self.offset);
          */
        }
        
        
        t.whenClick(0, -self.offset, self.settings.width,
            self.settings.height, function(ev) {
          var me = self;
          //console.log(se);
          me.clearScroll();
          return true;
        });
        
        
        
        
        
        /*
        t.whenScroll(0, -self.offset, self.settings.width,
            self.settings.height, function(ev) {
              scallable && (function() {
                self.offset += ev.stepY*vh/bh;
                self.offset = Math.max(self.minOffset, self.offset);
                self.offset = Math.min(self.maxOffset, self.offset);
              })();
            });
        */

        self["renderComp::Panel"](t, c, vw, vh, bw, bh);

        // t.whenScrollMove
        // console.log(self.layout.height);

      });
    }, "ScrollPanel");

    /*
     * 空面板
     */
    window.EmptyPanel = defClass(Component, function(settings) {
      var self = this;
      var default_settings = {
        page : undefined // 页面对象:用于检测各种事件是否发生
        ,
        top : 0// 绘制时，开始位置的y轴偏移量
        ,
        left : 0// 绘制时，开始位置的x轴偏移量
        ,
        width : 0// 绘制时，滚动面板范围的宽度
        ,
        height : 0// 绘制时，滚动面板范围的高度
        ,
        bgColor : "rgba(255,255,255,0)"
      };
      self.settings = $.extend({}, default_settings, settings);
      self.top = self.settings.top;
      self.left = self.settings.left;
      self.width = self.settings.width;
      self.height = self.settings.height;
    }, "EmptyPanel");

    defineFunction.call(EmptyPanel.prototype, "renderComp", function(t, c, vw,
        vh, bw, bh) {
      var self = this;
      var page = t;
      c.render(function() {
        c.t(self.left, self.top);
        c.fillStyle = self.settings.bgColor;
        c.fillRect(0, 0, self.width > 0 ? self.width : vw,
            self.height > 0 ? self.height : vh);
      });
    });

  } catch (e) {
    console.log(e);
  }

  return $.Component = Component;

});